/**
 * 1 题目描述

给定一个数组，它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易（多次买卖一支股票）。

注意：你不能同时参与多笔交易（你必须在再次购买前出售掉之前的股票）。

2 输入输出
示例 1:

输入: [7,1,5,3,6,4]

输出: 7

解释: 在第 2 天（股票价格 = 1）的时候买入，在第 3 天（股票价格 = 5）的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。随后，在第 4 天（股票价格 = 3）的时候买入，在第 5 天（股票价格 = 6）的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。

示例 2:

输入: [1,2,3,4,5]

输出: 4

解释: 在第 1 天（股票价格 = 1）的时候买入，在第 5 天 （股票价格 = 5）的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。

注意你不能在第 1 天和第 2 天接连购买股票，之后再将它们卖出。

因为这样属于同时参与了多笔交易，你必须在再次购买前出售掉之前的股票。

 

示例 3:

输入: [7,6,4,3,1]

输出: 0

解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

 

提示：

1 <= prices.length <= 3 * 10 ^ 4

0 <= prices[i] <= 10 ^ 4

3 解答
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/solution/tan-xin-suan-fa-by-liweiwei1419-2/里面有个作者写的很好（建议从这里看）

1）暴力搜素法
2）贪心算法
贪心策略：从第 i 天（这里 i >= 1）开始，与第 i - 1 的股价进行比较，如果股价有上升（严格上升），就将升高的股价（ prices[i] - prices[i- 1] ）记入总利润，按照这种算法，得到的结果就是符合题意的最大利润。

这道题 “贪心”方在于，对于 “今天的股价 - 昨天的股价”，得到的结果有 3 种可能：（1）正数（2）0（3）负数。贪心算法的决策是：只加正数。

时间复杂度：O(N)，这里 N 表示股价数组的长度；

空间复杂度：O(1)。

3） 动态规划 ---dp数组
可以用贪心算法解决的问题，一般情况下都可以用动态规划。

第一步，定义状态转移dp[i][j]：

第一维 i 表示索引为 i 的那一天（具有前缀性质，即考虑了之前天数的收益）能获得的最大利润；

第二维 j 表示索引为 i 的那一天是持有股票，还是持有现金。这里 0 表示持有现金（cash），1 表示持有股票（stock）。

第 2 步：状态转移方程（递推公式？？？）

状态从持有现金（cash）开始，到最后一天我们关心的状态依然是持有现金（cash）；每一天状态可以转移，也可以不动。因为不限制交易次数，除了最后一天，每一天的状态可能不变化，也可能转移。-----写代码的时候，可以不用对最后一天单独处理，输出最后一天，状态为 0 的时候的值即可。

如果dp[i]为现金时，可以是max（从dp[i-1]现金变为现金，dp[i-1]股票卖出变为现金）；如果dp[i]为股票时，可以是max（从dp[i-1]股票变为股票，dp[i-1]现金买入变为股票）；

第3步 确定起始（边界）

起始的时候：

如果什么都不做，dp[0][0] = 0；

如果买入股票，当前收益是负数，即 dp[0][1] = -prices[i]；

第4步 确定终止（边界）：

输出 dp[len - 1][0]，因为一定有 dp[len - 1][0] > dp[len - 1][1]。

附注：这里的空间复杂度可以降为常数阶，使用两个变量保存当前为现金或者股票时的收益

4代码

 */

// 贪心算法
var maxProfit_one = function(prices) {
    if(prices.length < 2) {
        return 0;
    }
    let profile = 0; // 收益，初始化为0
    for(let i = 1; i < prices.length; i++) {
        if(prices[i] - prices[i - 1] > 0) { // 如果当前价格高于前面的一个价格
            profile += prices[i] - prices[i - 1] // 收益增加为两者之差
        }
    }
    return profile;
}
// console.log(maxProfit([1, 2, 3, 4, 5]))

// 动态规划
var maxProfit = function(prices) {
    if(prices.length < 2) return 0; // 长度小于2，返回0
    let dp = []; // 初始化
    for(let i = 0; i < prices.length; i++) {
        dp[i] = new Array(2); // 将dp数组的每一项初始化数组，否则后面的dp[i][0]报错，因为数组有下标
    }
    // dp为二维数组，dp[i][0/1],表示现金/股票时的收益
    dp[0][0] = 0; // 必须初始化数组每一个项之后再用，初始化为0
    dp[0][1] = -prices[0]; // 第一线买了股票，收益为负
    for(let i = 1; i < prices.length; i++) {
        dp[i][0] = Math.max(dp[i - 1][0], dp[i-1][1] + prices[i]) // 表示第i天持有现金时候的收益，现金->现金 股票->现金
        dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]) // 表示第i天持有股票的时候的收益，现金->股票，股票->股票
    }
    return dp[prices.length - 1][0]
}
console.log(maxProfit([1, 2, 3, 4, 5]))
